#include "..\headers\ListOf.h"

// 本代码能实现加减乘除运算，但是本代码在输入时不能出现括号

#define InitSize 100
typedef int ElemType;

typedef struct Stack {
  ElemType *top;
  ElemType *base;
  int StackSize;
} SqStack;

// if stack is empty return true else return false
bool EmptyStack(SqStack S) { return S.top == S.base; }

int InitStack(SqStack &stack) {
  stack.base = (ElemType *)malloc(sizeof(Stack) * InitSize);
  if (!stack.base) {
    printf("ERROR:FAIL IN INITSTACK\n");
    return ERROR;
  }
  stack.top = stack.base;
  stack.StackSize = InitSize;
  return OK;
}

// push the element to stack top
int Push(SqStack &S, ElemType e) {
  if (S.top - S.base == S.StackSize) {
    printf("ERROR:IS FULLSTACK\n");
    return ERROR;
  }
  *S.top++ = e;
  return OK;
}

// pop the top element
int Pop(SqStack &S, ElemType &e) {
  if (S.top == S.base) {
    printf("ERROR:STACK IS EMPTY\n");
    return ERROR;
  }
  S.top--;
  e = *S.top;
  return OK;
}

// get top element in stack but do not change stack
int GetTop(SqStack S) {
  if (S.top == S.base) {
    return ERROR;
  }
  *S.top--;
  return *S.top;
}

// 把数字转为运算符,定义'*' = 1 ，'/' = 2，'+'= 3 '-' = 4 '=' = 5
char changeOpertor(int S) {
  switch (S) {
    case 1:
      return '*';
    case 2:
      return '/';
    case 3:
      return '+';
    case 4:
      return '-';
    case 5:
      return '=';
    default:
      return '0';  // 代表异常
  }
}

// 把运算符转为数字,定义'*' = 1 ，'/' = 2，'+'= 3 '-' = 4 '=' = 5
int changeNum(char S) {
  switch (S) {
    case '*':
      return 1;
    case '/':
      return 2;
    case '+':
      return 3;
    case '-':
      return 4;
    case '=':
      return 5;
    default:
      return 0;  // 代表异常
  }
}

// 判断运算符的关系（规定0是小于 1是大于）（是L 与R 相比）
int OperatorRelationship(char L, char R) {
  if (L == '0') return 0;
  if (R == '=') return 0;
  if (L == R) return 1;
  if ((L == '+' && R == '-') || (L == '-' && R == '+')) return 1;
  if ((L == '+' && R == '*') || (L == '+' && R == '/') ||
      (L == '-' && R == '*') || (L == '-' && R == '/'))
    return 0;
  if ((L == '*' && R == '+') || (L == '*' && R == '-') ||
      (L == '/' && R == '+') || (L == '/' && R == '-'))
    return 1;
  if ((L == '*' && R == '/') || (L == '/' && R == '*')) return 1;

  return 3;  // 代表异常情况
}

int Calculator(SqStack &operat, SqStack &Calculat, char Polynomial[]) {
  int num = 0, flag = 1, numbers, change, num1;
  // 1.finding the length of a polynomial and traversing
  // it（在多项式的结尾加上=为结束）
  Polynomial[strlen(Polynomial)] = '=';
  for (int i = 0; i < strlen(Polynomial);) {
    char R, temp;
    // 2.把多项式的运算符存入运算符栈
    if (Polynomial[i] == '+' || Polynomial[i] == '-' || Polynomial[i] == '*' ||
        Polynomial[i] == '/' || Polynomial[i] == '=') {
      R = Polynomial[i];
      // 3.判断运算符关系，存入还是输出运算（如果读到=则出栈运算）
      if (((EmptyStack(operat)) && R != '*' && R != '/') ||
          (OperatorRelationship(changeOpertor(GetTop(operat)), R))) {  // 存入
        Push(operat, changeNum(R));
      } else {  // 计算,R为运算符号
        if (R == '+') {
          Pop(Calculat, num);
          Push(Calculat, num + (Polynomial[++i] - '0'));
        } else if (R == '-') {
          Pop(Calculat, num);
          Push(Calculat, num - (Polynomial[++i] - '0'));
        } else if (R == '*') {
          Pop(Calculat, num);
          Push(Calculat, num * (Polynomial[++i] - '0'));
        } else if (R == '/') {
          Pop(Calculat, num);
          Push(Calculat, num / (Polynomial[++i] - '0'));
        } else if (R == '=') {
          while (!EmptyStack(operat)) {
            Pop(Calculat, num);
            Pop(operat, change);
            if (changeOpertor(change) == '+') {
              Pop(Calculat, num1);
              Push(Calculat, num + num1);
            }
            if (changeOpertor(change) == '-') {
              Pop(Calculat, num1);
              Push(Calculat, num - num1);
            }
            if (changeOpertor(change) == '*') {
              Pop(Calculat, num1);
              Push(Calculat, num * num1);
            }
            if (changeOpertor(change) == '/') {
              Pop(Calculat, num1);
              Push(Calculat, num / num1);
            }
          }
        }
      }  // end else
      i++;
      flag = 1;
    }                                                         // end if
    else if (Polynomial[i] >= '0' && Polynomial[i] <= '9') {  // 存入数字
      if (flag == 1) {
        Push(Calculat, (Polynomial[i] - '0'));
      } else {
        Pop(Calculat, numbers);
        Push(Calculat, (numbers * flag) + (Polynomial[i] - '0'));
      }  // end else
      flag = 10;
      i++;
    }  // end if
  }    // end for
  return GetTop(Calculat);
}  // end Calculator

int Check(char Polynomial[]) {
  int i = 0;
  while (Polynomial[i] != '\0') {
    if ((Polynomial[i] >= '0' && Polynomial[i] <= '9') ||
        (Polynomial[i] == '+' && Polynomial[i] == '-' && Polynomial[i] == '*' &&
         Polynomial[i] == '/'))
      continue;
    else
      return ERROR;
  }
  return OK;
}

int main() {
  SqStack OperatorStack, CalculatStack;
  int flag1, flag2;
  flag1 = InitStack(OperatorStack);
  flag2 = InitStack(CalculatStack);
  if (flag1 == ERROR && flag2 == ERROR) {
    return ERROR;
  }
  char Polynomial[81] = {0};
  gets(Polynomial);  // input char
  if(!Check(Polynomial)){
    printf("ERROR:INPUT UNDEFINED OPERATOR");
    return ERROR;
  }
  int result;
  result = Calculator(OperatorStack, CalculatStack, Polynomial);

  printf("%d", result);
}
